/*
Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通（但不一定有直接的公路相连，只要能间接通过公路可达即可）。经过调查评估，得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序，计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 )；随后的 N 
行对应村庄间道路的成本，每行给出一对正整数，分别是两个村庄的编号，以及此两村庄间道路的成本（也是正整数）。为简单起见，村庄从1到M编号。当N为0时，全部输入结束，相应的结果不要输出。
Output
对每个测试用例，在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通，则输出“?”。
Sample Input
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
Sample Output
3
?
 */
package com.yuan.algorithms.training20150807;

import java.io.InputStreamReader;
import java.util.Scanner;

/**
 * @author YouYuan
 * @eMail E-mail:1265161633@qq.com
 * @Time 创建时间：2015年8月20日 下午4:26:47
 * @Explain 说明:题目的M范围有问题，数组要开大些，不然报错误答案，坑！
 */
public class 图论_畅通工程 {

	static Scanner in = new Scanner(new InputStreamReader(System.in));
	static int[][] map = new int[105][105];
	static boolean[] mark = new boolean[105];
	static int n, m;
	static final int MAX = 0xfffffff;
	public static void main(String[] args) {
		while(in.hasNext()) {
			n = in.nextInt();
			m = in.nextInt();
			if (n==0) {
				break;
			}
			initialise();
			for (int i = 0; i < n; i++) {
				int a = in.nextInt();
				int b = in.nextInt();
				int cost = in.nextInt();
				if (map[a][b] > cost) {
					map[a][b] = map[b][a] = cost;
				}
			}
			prime();
		}
	}
	private static void prime() {
		int sum = 0;
		mark[1] = true;
		for (int i = 1; i < m; i++) {
			int min = MAX;
			int index = -1;
			for (int j = 1; j <= m; j++) {
				if (!mark[j] && map[1][j] < min) {
					min = map[1][j];
					index = j;
				}
			}
			if (index == -1) {//没有找到路径
				System.out.println("?");
				return;
			}
			sum += min;
			mark[index] = true;
			for (int j = 1; j <= m; j++) {
				if (!mark[j] && map[1][j] > map[index][j]) {
					map[1][j] = map[index][j];
				}
			}
		}
		System.out.println(sum);
	}
	
	/**
	 * 初始化
	 */
	private static void initialise() {
		for (int i = 1; i <= m; i++) {
			mark[i] = false;
			for (int j = 1; j <= m; j++) {
				map[i][j] = MAX;
			}
		}
	}

}
